package com.mostsnails.common.base.utils.validator;

import com.mostsnails.common.base.constant.CheckType;
import com.mostsnails.common.base.utils.common.EmojiUtils;
import org.apache.commons.lang3.StringUtils;

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.text.SimpleDateFormat;
import java.util.regex.Pattern;

/**
 * 自定义检测
 * 1.表情符号包含检测
 *
 * @Author MostSnails
 * @Version 1.0
 */
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = CustomValid.CheckValidator.class)
public @interface CustomValid {
    String message() default ""; // 自定义异常返回信息

    CheckType type(); // 自定义校验字段

    Class<?>[] groups() default {};

    Class<? extends javax.validation.Payload>[] payload() default {};

    /**
     * 校验实现
     * 实现ConstraintValidator接口，第一个是自定义的注解，第二个是注解使用的类型。
     */
    class CheckValidator implements ConstraintValidator<CustomValid, Object> {
        private CheckType type;

        @Override
        public void initialize(CustomValid constraintAnnotation) {
            this.type = constraintAnnotation.type();
        }

        @Override
        public boolean isValid(Object value, ConstraintValidatorContext context) {
            return CheckValidator.validate(type, value);
        }

        /**
         * 校验方法
         * 验证传入的枚举值，是否符合规则
         *
         * @param type
         * @return true：验证成功；false：验证失败
         */
        public static boolean validate(CheckType type, Object obj) {
            if (null == obj || null == type) {
                //空不校验
                return true;
            }
            if (!(obj instanceof String)) {
                //不是String 返回false
                return false;
            }
            //获取参数
            String str = obj.toString();
            if (StringUtils.isEmpty(str)) {
                //空字符串不校验
                return true;
            }
            //日期格式不适用正则
            if ("Date".equals(type.value)) {
                SimpleDateFormat sdf = new SimpleDateFormat(type.regular);
                try {
                    sdf.parse(str);
                } catch (Exception e) {
                    return false;
                }
                return true;
            }
            //表情符号检测
            if ("Emoji".equals(type.value)) {
                return EmojiUtils.containsEmoji(str) ? false : true;
            }
            //使用正则校验
            return Pattern.matches(type.regular, str);
        }
    }
}
